package com.leo.auth.config;

import com.leo.common.core.constant.AdditionalToken;
import com.leo.common.core.constant.CacheConstants;
import com.leo.common.core.constant.SecurityConstants;
import com.leo.common.core.enums.ExceptionCodeEnum;
import com.leo.common.core.util.MessageUtils;
import com.leo.common.core.util.SpringContextHolder;
import com.leo.common.security.common.entity.SecurityUser;
import com.leo.common.security.server.handler.UserAuthenticationChecks;
import io.micrometer.core.instrument.util.StringUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsChecker;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * <p>
 * UsernamePasswordAuthenticationProvider
 * </p>
 *
 * @author ：Leo
 * @since ：2021-04-06 16:20
 */
public class UsernamePasswordAuthenticationProvider implements AuthenticationProvider {

	private final UserDetailsChecker detailsChecker = new UserAuthenticationChecks();

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED" : authentication.getName();
		String password = (String) authentication.getCredentials();
		// 认证用户名
		if (!"user".equals(username) && !"admin".equals(username)) {
			throw new BadCredentialsException(SpringContextHolder.getBean(MessageUtils.class)
					.get(ExceptionCodeEnum.AUTH_USER_NAME_NOT_FOUND.getMsg(), new String[] { username }));
		}
		// 认证密码，暂时不加密
		if ("user".equals(username) && !"123".equals(password)
				|| "admin".equals(username) && !"admin".equals(password)) {
			throw new BadCredentialsException(
					SpringContextHolder.getBean(MessageUtils.class).get(ExceptionCodeEnum.AUTH_BAD_PWD.getMsg()));
		}
		SecurityUser securityUser = null;

		String userNameCacheKey = CacheConstants.GLOBALLY + CacheConstants.USER_DETAILS + ":" + username;

		String[] permissions = new String[2];
		permissions[0] = "user:add";
		permissions[1] = "dict:add";
		Set<String> authsSet = new HashSet<>(Arrays.asList(permissions));

		Collection<? extends GrantedAuthority> authorities = AuthorityUtils
				.createAuthorityList(authsSet.toArray(new String[0]));

		securityUser = new SecurityUser(1L, 1, "admin", SecurityConstants.BCRYPT + password, AdditionalToken.ADMIN_USER,
				"管理员", "昵称", authorities);

		detailsChecker.check(securityUser);

		UsernamePasswordAuthenticationToken ut = new UsernamePasswordAuthenticationToken(securityUser,
				authentication.getCredentials(), securityUser.getAuthorities());
		ut.setDetails(authentication.getDetails());

		return ut;
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
	}

	private Set<GrantedAuthority> listUserGrantedAuthorities(String username) {
		Set<GrantedAuthority> authorities = new HashSet<>();
		if (StringUtils.isEmpty(username)) {
			return authorities;
		}
		authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
		if ("admin".equals(username)) {
			authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
		}
		return authorities;
	}

}
